5 * @covers Argon2Password
7 * @covers ParameterizedPassword
9 * @phpcs:disable Generic.Files.LineLength
11 class Argon2PasswordTest
extends PasswordTestCase
{
13 public function setUp() {
15 if ( !defined( 'PASSWORD_ARGON2I' ) ) {
16 $this->markTestSkipped( 'Argon2 support not found' );
21 * Return an array of configs to be used for this class's password type.
25 protected function getTypeConfigs() {
28 'class' => Argon2Password
::class,
30 'memory_cost' => 1024,
40 public static function providePasswordTests() {
44 ':argon2:$argon2i$v=19$m=1024,t=2,p=2$RHpGTXJPeFlSV2NDTEswNA$VeW7rumZY4pL8XO4KeQkKD43r5uX3eazVJRtrFN7lNc',
49 ':argon2:$argon2i$v=19$m=2048,t=5,p=3$MHFKSnh6WWZEWkpKa09SUQ$vU92h/8hkByL5VKW1P9amCj054pZILGKznAvKWAivZE',
54 ':argon2:$argon2i$v=19$m=1024,t=2,p=2$bFJ4TzM5RWh2T0VmeFhDTA$AHFUFZRh69aZYBqyxn6tpujpEcf2JP8wgRCPU3nw3W4',
59 ':argon2:$argon2i$v=19$m=1024,t=2,p=2$UGZqTWJRUkI1alVNTGRUbA$RcASw9XUWjCDO9WNnuVkGkEylURUW/CcNwSffdFwN74',
64 if ( defined( 'PASSWORD_ARGON2ID' ) ) {
65 // @todo: Argon2id cases
66 $result = array_merge( $result, [] );
73 * @dataProvider provideNeedsUpdate
75 public function testNeedsUpdate( $updateExpected, $hash ) {
76 $password = $this->passwordFactory
->newFromCiphertext( $hash );
77 $this->assertSame( $updateExpected, $password->needsUpdate() );
80 public function provideNeedsUpdate() {
82 [ false, ':argon2:$argon2i$v=19$m=1024,t=2,p=2$bFJ4TzM5RWh2T0VmeFhDTA$AHFUFZRh69aZYBqyxn6tpujpEcf2JP8wgRCPU3nw3W4' ],
83 [ false, ':argon2:$argon2i$v=19$m=1024,t=2,p=2$<whatever>' ],
84 [ true, ':argon2:$argon2i$v=19$m=666,t=2,p=2$<whatever>' ],
85 [ true, ':argon2:$argon2i$v=19$m=1024,t=666,p=2$<whatever>' ],
86 [ true, ':argon2:$argon2i$v=19$m=1024,t=2,p=666$<whatever>' ],
90 public function testPartialConfig() {
91 // The default options changed in PHP 7.2.21 and 7.3.8. This seems to be the only way to
92 // fetch them at runtime.
93 $options = password_get_info( password_hash( '', PASSWORD_ARGON2I
) )['options'];
95 $factory = new PasswordFactory();
96 $factory->register( 'argon2', [
97 'class' => Argon2Password
::class,
101 $partialPassword = $factory->newFromType( 'argon2' );
102 $partialPassword->crypt( 'password' );
104 $factory2 = new PasswordFactory();
105 $factory2->register( 'argon2', [
106 'class' => Argon2Password
::class,
110 $fullPassword = $factory2->newFromCiphertext( $partialPassword->toString() );
112 $this->assertFalse( $fullPassword->needsUpdate(),
113 'Options not set for a password should fall back to defaults'